<?php 

class ReportAnalytic {
/*
活动插件XML字符串分析类
兼容性: MLDKP1.5
构建后调用load_report_xml($xmlstr)载入数据;

*/

	public $XML;

	public $dStartTime, $dEndTime;
	public $strRaidTitle, $strRaidZone, $strRaidClass, $intRaidMemberCount, $strRaidNote;
	public $arrPlayers, $arrBossKills, $arrJoins, $arrLeaves, $arrLoots;
	public $dataversion, $exporter;

	public $strError;

	private $raidid ;

	private $Xplayers;
	private $Xjoins;
	private $Xleaves;
	private $Xloots;


	function __construct() {
		
	}

	public function create_report() {
		$this->sqlCreateRaid(); //创建Raid记录
		$this->sqlClearRaidEvent(); //删除全部已有raid事件
		$this->sqlUpdatePlayers(); //更新Player
		$this->sqlAddRaidPlayer(); //添加Player到Raid
		$this->sqlJoinEvents(); //添加加入事件到Raid
		$this->sqlLeaveEvents(); //添加离开事件到Raid
		$this->sqlLootEvents(); //添加物品事件到Raid
		$this->sqlBossKillEvents(); //添加击杀事件到Raid
	}


	//载入来自活动插件的xml字符串
	public function load_report_xml($str) {
		$str = str_replace("\n","",$str);
		$str = str_replace("PlayerInfos>","playerinfos>",$str);
		$str = str_replace("Join>","join>",$str);
		$str = str_replace("Joins>","joins>",$str);
		$str = str_replace("Leave>","leave>",$str);
		$str = str_replace("Leaves>","leaves>",$str);
		$str = str_replace("Loot>","loot>",$str);
		$str = str_replace("Loots>","loots>",$str);
		$str = str_replace("Note>","note>",$str);
		$str = str_replace("ItemName>","itemname>",$str);
		$str = str_replace("ItemID>","itemid>",$str);
		$str = str_replace("Icon>","icon>",$str);
		$str = str_replace("Player>","player>",$str);
		$str = str_replace("Time>","time>",$str);
		$str = str_replace("Zone>","zone>",$str);
		$str = str_replace("Boss>","boss>",$str);
		$str = str_replace("Class>","class>",$str);
		$str = str_replace("Subclass>","subclass>",$str);
		$str = str_replace("BossKills>","bosskills>",$str);
		$str = str_replace("Color>","color>",$str);
		$str = str_replace("Count>","count>",$str);
		$str = str_replace("Costs>","costs>",$str);
		$this->XML = new DOMDocument(); //创建DOM对象
		$this->XML->loadXML($str); //加载XML

		$this->analytic(); //分析,初始化变量和数组
		$this->format(); //数据格式化
	}

	//分析全部数据,初始化变量和数组
	public function analytic() {
		if ($this->check_xml()) {
			$this->dStartTime = $this->getStartTime();
			$this->dEndTime = $this->getEndTime();
			$this->strRaidTitle = $this->getRaidTitle($_POST["raid_title"]);
			$this->dataversion = $this->getDataVersion();
			$this->exporter = $this->getExporter();
			
			$this->arrPlayers = $this->getArrayByTagN("playerinfos","name");
			$this->arrBossKills = $this->getArrayByTagN("bosskills","name");
			$this->arrJoins = $this->getArrayByTag("joins");
			if ($this->hasnode('join') and !$this->hasnode('joins')) {$this->arrJoins = $this->getArrayByTag("join");}
			$this->arrLeaves = $this->getArrayByTag("leaves");
			if ($this->hasnode('leave') and !$this->hasnode('leaves')) {$this->arrLeaves = $this->getArrayByTag("leave");}
			$this->arrLoots = $this->getArrayByTag("loots");
			if ($this->hasnode('loot') and !$this->hasnode('loots')) {$this->arrLoots = $this->getArrayByTag("loot");}
		}else{
			$this->strError .= "check_xml error.";
		}
	}

	//格式化数据
	public function format() {
		//时间标准化
		$this->arrJoins = $this->covFormatTime($this->arrJoins);
		$this->arrLeaves = $this->covFormatTime($this->arrLeaves);
		$this->arrBossKills = $this->covFormatTime($this->arrBossKills);
		$this->arrLoots = $this->covFormatTime($this->arrLoots);

		//事件清理 ...

		//
		$this->arrLoots = $this->parseLoots($this->arrLoots);
	}

	//显示一个debugg信息框
	public function debuggshow() {
		echo "<textarea style='width:600px;height:400px;'>";
		echo "startdate: ".$this->dStartTime;
		echo "\n";
		echo "enddate: ".$this->dEndTime;
		echo "\n";
		echo "title: ".$this->strRaidTitle;
		echo "\n";
		echo "arrPlayers:";
		echo "\n\n";
		print_r ($this->arrPlayers);
		echo "\n arrBossKills:";
		echo "\n\n";
		print_r ($this->arrBossKills);
		echo "\n arrJoins:";
		echo "\n\n";
		print_r ($this->arrJoins);
		echo "\n arrLeaves:";
		echo "\n\n";
		print_r ($this->arrLeaves);
		echo "\n arrLoots:";
		echo "\n\n";
		print_r ($this->arrLoots);
		echo "\n";
		echo "\n";
		echo "\n";
		print ($this->error_info);
		echo "</textarea>";
	}

	//检查XML有效性,必须有起始结束时间和成员列表
	private function check_xml() {
		$this->error_info="";
		if (!$this->hasnode('start')) {$this->error_info .= "/缺少活动起始时间";}
		if (!$this->hasnode('end')) {$this->error_info .= "/缺少活动结束时间";}
		if (!$this->hasnode('playerinfos')) {$this->error_info .= "/缺少成员信息,请检查插件版本";}

		if ($this->error_info<>"") {
			print $this->error_info;
			return false;
		}else{
			return true;
		}
	}

	//检查节点是否存在
	private function hasnode($node) {
		$nodecount = $this->XML->getElementsByTagName($node);
		if ($nodecount->length < 1) {
			return false;
		}else{
			return true;
		}
	}

	//获取开始时间戳
	private function getStartTime() {
		if ($timestr = $this->XML->getElementsByTagName("start")->item(0)->nodeValue) {
			return getStandardDate($timestr);
		}else{
			$this->error_info .= "/获取开始时间错误";
			return false;
		}
	}

	//获取结束时间戳
	private function getEndTime() {
		if ($timestr = $this->XML->getElementsByTagName("end")->item(0)->nodeValue) {
			return getStandardDate($timestr);
		}else{
			$this->error_info .= "/获取结束时间错误";
			return false;
		}
	}
	
	//获取XML版本标识
	public function getDataVersion() {
		if ($_POST['xmlversion'] != '') {
			return $_POST['xmlversion'];
		}elseif ($version = $this->XML->getElementsByTagName("version")->item(0)->nodeValue) {
			return $version;
		}else{
			return "unknow";
		}
	}
	
	//获取报告导出者
	public function getExporter() {
		if ($exporter = $this->XML->getElementsByTagName("exporter")->item(0)->nodeValue) {
			return $exporter;
		}else{
			return "unknow";
		}
	}

	//获取活动标题 表单>备注>地区+ID>..
	private function getRaidTitle($strFormTitle) {
		$note = $this->XML->getElementsByTagName("note")->item(0)->nodeValue;
		$zone = $this->XML->getElementsByTagName("zone")->item(0)->nodeValue;
		$instanceid = $this->XML->getElementsByTagName("instanceid")->item(0)->nodeValue;

		if ($strFormTitle) {
			return $strFormTitle;
		}elseif ($zone) {
			return $zone.$instanceid;
		}elseif ($note) {
			return $note;
		}else{
			return "未命名活动";
		}
	}

	//获取指定节点下的各子节点的各子节点数据,返回一个2维数组
	public function getArrayByTag($tag) {
		if (!$tar = $this->XML->getElementsByTagName($tag)->item(0)) {return false;};
		if ($tar->hasChildNodes()) {
			for ($k=0; $k < $tar->childNodes->length; $k++) {
				$unit = $tar->childNodes->item($k);
				for ($j=0; $j < $unit->childNodes->length; $j++) {
					if ($unit->childNodes->item($j)->tagName != '') {
						$n[$k][$unit->childNodes->item($j)->tagName] = $unit->childNodes->item($j)->nodeValue;
					}
				}
			}
			return $n;
		}else{
			return null;
		}
	}


	//获取指定节点下的各子节点的各子节点数据,返回一个2维数组
	public function getArrayByTagN($tag,$name) {
		if (!$tar = $this->XML->getElementsByTagName($tag)->item(0)) {return false;};
		if ($tar->hasChildNodes()) {
			foreach ($tar->childNodes as $unit) { //遍历条目unit
				if ($unit->nodeType != 1) continue;
				//echo "/".$unit->nodeType;
				if ($m = $unit->getElementsByTagName($name)->item(0)->nodeValue) { //找到$name节点,并把值作为数组的1维下标
					foreach ($unit->childNodes as $tag) { //遍历条目中的元素tag
						if ($tag->tagName != '') {
							$n[$m][$tag->tagName] = $tag->nodeValue;
						}
					}
				}
			}
			return $n;
		}else{
			return null;
		}
	}

	//转换数组中出现的time为标准时间格式
	private function covFormatTime($arr) {
		foreach ($arr as &$sub) {
			if (array_key_exists('time',$sub)) {
				$sub['time'] = getStandardDate($sub['time']);
			}
		}
		return $arr;
	}

	//尝试深入解析物品信息
	private function parseLoots($arrLoots) {
		foreach ($arrLoots as &$loot) {
			if ($ids = split(':',$loot['itemid'])) { //itemid只保留主ID部分
				$loot['itemid'] = $ids[0];
			}
		}
		return $arrLoots;
	}


	//加入离开事件的整理,清理过频数据

	//创建or更新活动记录 获取ID
	public function sqlCreateRaid() {
		$raid_name = $this->strRaidTitle;
		$raid_concentratetime = $this->dStartTime;
		$raid_actiontime = $this->dStartTime;
		$raid_endtime = $this->dEndTime;
		$raid_personnel = $this->getRaidMemberCount();
		$raid_player = '';
		$raid_commander = '';
		$raid_plan = $_POST['raid_plan'];
		$raid_step = 1;
		$raid_class = $_POST['class_name'];

		$sql = "select * from raid where raid_concentratetime='$this->dStartTime'";
		$result = mysql_query($sql);
		if (mysql_num_rows($result)>0) {
			$row = mysql_fetch_array($result);
			$this->raidid = $row['id'];
			$sql = "UPDATE raid SET raid_name='$raid_name', raid_endtime='$raid_endtime', raid_personnel='$raid_personnel', raid_player='$raid_player', raid_commander='$raid_commander', raid_plan='$raid_plan', raid_step='$raid_step', raid_class='$raid_class' WHERE raid_concentratetime='$this->dStartTime'";
			if (!mysql_query($sql)) {$this->error_info .= "\n更新活动记录错误$sql ".mysql_error();}
		}else{
			$sql="INSERT INTO raid (raid_name,raid_concentratetime,raid_actiontime,raid_endtime,raid_personnel,raid_player,raid_commander,raid_plan,raid_step,raid_class) ".
				"values ('$raid_name','$raid_concentratetime','$raid_actiontime','$raid_endtime','$raid_personnel','$raid_player','$raid_commander','$raid_plan','$raid_step','$raid_class')";
			if (!$rs = mysql_query($sql)) {$this->error_info .= "\n添加活动记录错误$sql ".mysql_error();}
			$this->raidid = mysql_insert_id();
			echo "882:".$this->raidid."]";
		}
	}

	public function getRaidMemberCount() {
		return count($this->arrPlayers);
	}

	private function sqlClearRaidEvent() {
		$sql = "DELETE FROM raid_event WHERE event_raidid='$this->raidid'";
		if (!mysql_query($sql)) {
			$this->error_info .= "\n清理旧活动事件错误$sql ".mysql_error();
			return false;
		}
		return true;
	}


	//更新活动中player
	public function sqlUpdatePlayers() { //arrPlayers
		$player_BaseDKP = 0;
		$player_DKP = 0;
		$player_looted = '';
		foreach ($this->arrPlayers as $player) {
			$player_name = $player['name'];
			$player_level = getPlayerLevel($player['level']);
			$player_race = getFormatRaceName($player['race']);
			$player_class = getFormatProfessionName($player['class']);
			$player_jointime = getStandardDate();

			$sql="select * from player where player_name='".$player['name']."'";
			$result = mysql_query($sql);
			if (mysql_num_rows($result)==0) { //判断是否已存在该玩家
				echo "/1";
				$sql = "INSERT INTO player (player_name, player_level, player_race, player_class, player_jointime, player_looted) ".
				"VALUES ( '$player_name', '$player_level', '$player_race', '$player_class', '$player_jointime', '$player_looted' )";
				if (!mysql_query($sql)) {$this->error_info .= "\n添加人员错误$sql ".mysql_error();}
			}else{ //已存在则更新
				$sql = "UPDATE player SET player_level='$player_level', player_race='$player_race', player_class='$player_class' WHERE player_name='".$player['name']."'";
				if (!mysql_query($sql)) {$this->error_info .= "\n更新人员错误$sql ".mysql_error();}
			} 
		} //for END.
		return true;
	}

	//在Raid中写入参与人员ID
	public function sqlAddRaidPlayer() {
		$names = $this->getPlayerNameStr();
		$sql="UPDATE raid SET raid_player='$names' where id=".$this->raidid;
		if (!$result = mysql_query($sql)) {
			$this->error_info .= "\n写入人员串未能找到活动$sql ".mysql_error();
			return false;
		}
		return true;
	} 

	//获取player名字的串联字串
	private function getPlayerNameStr() {
		$str = ',';
		foreach ($this->arrPlayers as $player) {
			$str .= $player['name'].',';
		}
		return $str;
	}


	//更新加入事件
	public function sqlJoinEvents() {
		$event_raidid = $this->raidid;
		$event_class = '加入';
		$event_dkp = 0;
		$event_object2 = '';

		foreach ($this->arrJoins as $event) {
			$event_time = $event['time'];
			$event_object = getIDByName($event['player']);
			$vals .= "('$event_raidid', '$event_time', '$event_class', '$event_dkp', '$event_object', '$event_object2'),";
		}
		$vals = rtrim($vals,",");
		$sql = "INSERT INTO raid_event (event_raidid, event_time, event_class, event_dkp, event_object, event_object2) VALUES ".$vals;
		if (!mysql_query($sql)) {
			$this->error_info .= "\n加入事件写入错误$sql ".mysql_error();
			return false;
		}
	}

	//更新离开事件
	public function sqlLeaveEvents() {
		$event_raidid = $this->raidid;
		$event_class = '离开';
		$event_dkp = 0;
		$event_object2 = '';

		foreach ($this->arrLeaves as $event) {
			$event_time = $event['time'];
			$event_object = getIDByName($event['player']);
			$vals .= "('$event_raidid', '$event_time', '$event_class', '$event_dkp', '$event_object', '$event_object2'),";
		}
		$vals = rtrim($vals,",");
		$sql = "INSERT INTO raid_event (event_raidid, event_time, event_class, event_dkp, event_object, event_object2) VALUES ".$vals;
		if (!mysql_query($sql)) {
			$this->error_info .= "\n离开事件写入错误$sql ".mysql_error();
			return false;
		}
	}

	private function getLootEventClass($loot) {
		if ($loot['note'] == 'BOE' || $loot['player'] == '银行' || $loot['player'] == '銀行') {return "仓库";}
		if ($loot['note'] == 'ENC' || $loot['player'] == '分解' || $loot['player'] == '分解') {return "分解";}
		return "拾取";
	}

	private function getLootDKP($loot) {
		$dkp = $loot['costs'];
		if ($loot['note']) {
			$dkp = $loot['note'];
		}
		return $dkp;
	}

	//更新拾取事件
	public function sqlLootEvents() {
		foreach ($this->arrLoots as $loot) {
			$event_raidid = $this->raidid;
			$event_class = $this->getLootEventClass($loot);
			$event_dkp = $this->getLootDKP($loot);
			if ($arr = split('/',$loot['note'])) {
				if (is_numeric($arr[1]) && $arr[1] != '') {$event_dkp2 = $arr[1];}else{$event_dkp2= '';}
			}
			$event_time = $loot['time'];
			$event_object = getIDByName($loot['player']);
			$event_object2 = $loot['itemname'].'#'.$loot['itemid'];
			$event_object2_tooltip = $loot['tooltip'];
			$vals .= "('$event_raidid', '$event_time', '$event_class', '$event_dkp', '$event_dkp2', '$event_object', '$event_object2', '$event_object2_tooltip'),";
		}
		$vals = rtrim($vals,",");
		$sql = "INSERT INTO raid_event (event_raidid, event_time, event_class, event_dkp, event_dkp2, event_object, event_object2, event_object2_tooltip) VALUES ".$vals;
		if (!mysql_query($sql)) {
			$this->error_info .= "\n拾取事件写入错误$sql ".mysql_error();
			return false;
		}
	}


	//更新击杀事件
	public function sqlBossKillEvents() {
		$event_raidid = $this->raidid;
		$event_class = '击杀';
		$event_dkp = 0;
		$event_object = '-';

		foreach ($this->arrBossKills as $event) {
			$event_time = $event['time'];
			$event_object2 = $event['bosskill'];
			$vals .= "('$event_raidid', '$event_time', '$event_class', '$event_dkp', '$event_object', '$event_object2'),";
		}
		$vals = rtrim($vals,",");
		$sql = "INSERT INTO raid_event (event_raidid, event_time, event_class, event_dkp, event_object, event_object2) VALUES ".$vals;
		if (!mysql_query($sql)) {
			$this->error_info .= "\n击杀事件写入错误$sql ".mysql_error();
			return false;
		}
	}


	//滤掉多余的加入离开事件,由插件重复记录引起
	private function fixJoinLeaveEvents($arr){
		$arr2 = $arr;
		foreach ($arr as $sub) {
			foreach ($arr2 as $sub2) {
				$key = key($arr2);
				if ($sub['name'] ==$sub2['name'] && DateDiff($sub['time'], $sub2['time'] )<300) {
					unset($arr2[$key]);
					unset($arr[$key]);
				}
			}
		}
		return;
	}


	//滤掉暂时的离线事件: 同一角色在离线事件后的5分钟内如果发现有加入事件则删除这对事件.
	private function fixOfflineEvents() {
		for ($jindex=0; $jindex<=count($joinevents)-1; $jindex=$jindex+1) {
			if ($joinevents[$jindex][0]!="") {
				for ($lindex=0; $lindex<=count($leaveevents)-1; $lindex=$lindex+1) {
					if ($leaveevents[$lindex][0]!="" && $joinevents[$jindex][0]!="") {
						if ($joinevents[$jindex][0]==$leaveevents[$lindex][0]) {
							if (($DateDiff["n"][$joinevents[$jindex][1]][$leaveevents[$lindex][1]]>-5 && $DateDiff["n"][$joinevents[$jindex][1]][$leaveevents[$lindex][1]]<0)) {
								//Or (DateDiff("n",joinevents(jindex,1),leaveevents(lindex,1)) < 5 And DateDiff("n",joinevents(jindex,1),leaveevents(lindex,1)) > 0)
								print $joinevents[$jindex][0]." 离线修正,删除值对: 加入".$joinevents[$jindex][1]." , 离开".$leaveevents[$lindex][1]." , ".$DateDiff["n"][$joinevents[$jindex][1]][$leaveevents[$lindex][1]]."<br>";
								$joinevents[$jindex][0]="";
								$joinevents[$jindex][1]="";
								$leaveevents[$lindex][0]="";
								$leaveevents[$lindex][1]="";
							} 
						} 
					} 
				}
			} 
		}
		return $function_ret;
	} 



}




?>
